﻿using System;
using System.Collections.Generic;
using Grishko.DataTier;
using OutdoorLib.Context;
using Grishko.SerilizeTools;
using OutdoorLib.BaseEntity.WS;

using OutdoorLib.BaseEntity.Contract;
using OutdoorLib.BaseEntity.Constraction;
using OutdoorLib.BaseEntity.Dictionary;
using OutdoorLib.BaseEntity.Face;
using OutdoorLib.BaseEntity.Infrastructure;
using System.Data;


namespace OutdoorLib.BaseEntity.Agency 
{
    /// <summary>
    /// Агентство 
    /// </summary>
    [TagNameInfo (TagName ="Agency")]
    public class AgencyEntity : Face_U 
    {        
        public class AgencySettingInfo : SettingInfo, IFileSignature
        {
            public override bool TypeMapperOn
            {
                get
                {
                    return false;
                }
            }

            public override void Load()
            {                
                base.Load();
            }

            private double _CentrMapX = Convert.ToDouble("37,63641357421875");
            private double _CentrMapY = Convert.ToDouble ("55,751076525769044");

            public double CentrMapX { get { return _CentrMapX; } set { _CentrMapX = value; } }
            public double CentrMapY { get { return _CentrMapY; } set { _CentrMapY = value; } }

            #region IFileSignature Members

            public virtual string Directory
            {
                get { return "Agency"; }
            }

            public virtual string FileName
            {
                get { return AgencyID + ".xml"; }
            }

            #endregion            
        }
        public override bool TypeMapperOn
        {
            get
            {
                return false;
            }
        }

        private AgencySettingInfo _Settings = new AgencySettingInfo();
        public AgencySettingInfo Settings { get { return _Settings; } }
                

        #region Properties



        private EntityList _DictionarySettings = new EntityList();
        /// <summary>
        /// Карта справочников, 
        /// В списке преречень собственных типов справочников. 
        /// </summary>
        public EntityList DictionarySettings { get { return _DictionarySettings; } set { _DictionarySettings = value; } }


       

        private EntityList _AdressPrograms = new EntityList();
        /// <summary>
        /// Доступные агентсву адресные программы
        /// </summary>
        public EntityList AdressPrograms { get { return _AdressPrograms; } set { _AdressPrograms = value; } }

        //Департаменты
        private Department _Departments = new Department();
        /// <summary>
        /// Дерево оргструктуры
        /// </summary>
        [SrchItemInfo(TxtPropertyName = "Подразделения")]
        public Department Department { get { return _Departments; } set { _Departments = value; } }


        /// <summary>
        /// выдать группу определенного типа 
        /// </summary>
        /// <param name="GroupType"></param>
        /// <returns></returns>
        public EntityList GetGroupItems(Group.EGroupType GroupType)
        {
            EntityList result = new EntityList();
            SqlTools tls = new SqlTools(AppContext.GetSC());            
            DataSet DS = tls.ExecuteSql(string.Format("select ObjectXml  from vSrchStorageLinks  where tagname ='{0}'", GroupType.ToString()));            
            if(DS.Tables .Count ==0)
                return result;
            foreach (DataRow rw in  DS.Tables[0].Rows )
            {
                string sXml=rw[0].ToString ();
                EntitySingle obj = (EntitySingle)EntityActivator.CreateInstance(sXml);
                obj.ReadXml(sXml);
                result .Add (obj as EntitySingle );
            }
                        
            
            return result ;
        }

        public EntityList _Discounts = new EntityList();
        /// <summary>
        /// Скидки
        /// </summary>
        [SrchItemInfo(TxtPropertyName = "Скидки", ListType = typeof(Discount))]
        public EntityList Discounts { get { return _Discounts; } set { _Discounts = value; } }


        


        private FilterList _FilterList = new FilterList();
        /// <summary>
        /// список общих фиьтров агенства
        /// </summary>
        public FilterList FilterList
        {
            get { return _FilterList; }
            set { _FilterList = value; }

        }

        ///// <summary>
        ///// Хранилище переопределенных фабрик классов
        ///// </summary>
        private WS_FactoryList _WS_FactoryList = new WS_FactoryList();
        public WS_FactoryList WS_FactoryList { get { return _WS_FactoryList; } }
        #endregion

        #region Methods
        /// <summary>
        /// Установить движок бизнес правил для запрашиваемого объекта
        /// </summary>
        /// <param name="Instance"></param>
        /// <param name="BRE"></param>
        //public void SetBusinesRulesEngine(BusinessRulesEntity Instance, ref BusinesRulesEngine BRE)
        //{
        //    if (Instance is ContractEntity && (null == BRE))
        //    {

        //        BRE = new Contract_BusinesRulesEngine() { Owner = Instance };

        //    }

        //    if (Instance is ContractSurfaceItem && (null == BRE))
        //    {
        //        BRE = new Contract_BusinesRulesEngine() { Owner = Instance };

        //    }



        //    if (Instance is ConstractionEntity && (null == BRE))
        //    {
        //        BRE = new Constraction_BusinesRulesEngine() { Owner = Instance };

        //    }

        //}

        /// <summary>
        /// найти депатамент
        /// </summary>
        /// <param name="_Agency"></param>
        /// <param name="DepartmentID"></param>
        /// <returns></returns>
        public Department GetDepartment(string DepartmentID)
        {
            Department res = null;
            Func<Department, bool> IsIm = delegate(Department CurrentDepartment)
            {
                bool isOk = (CurrentDepartment.ID == DepartmentID);
                if (isOk) res = CurrentDepartment;
                return isOk;
            };
            NextDeparment(Department, IsIm);
            return res;
        }

        /// <summary>
        /// Вернуть сотрудников указанного департамента - если WitchChild - с дочерними депратаментами
        /// </summary>
        /// <param name="WitchChild"></param>
        /// <param name="DepartmentID"></param>
        /// <returns></returns>
        public List<Employeer> GetEmplList(bool WitchChild, Department _Department)
        {
            if (!WitchChild) return _Department.Employees.ToList<Employeer>()   ;

            List<Employeer> res = new List<Employeer>();
            Func<Department, bool> GetEmpl = delegate(Department CurrentDepartment)
            {
                res.AddRange(CurrentDepartment.Employees.ToArray<Employeer>());
                return false;
            };
            NextDeparment(_Department, GetEmpl);
            return res;
        }
        
        /// <summary>
        /// Вернуть сотрудника - основной метод поиска сотрудника в агентстве -просматривает все депратаменты и отыскивает нужного
        /// </summary>
        /// <param name="ID"></param>
        /// <returns></returns>
        public Employeer GetEmployeer(string ID)
        {
            List<Employeer> l = GetEmplList(true, _Departments);
            foreach (Employeer i in l)            
            {
                if (i.ID == ID)
                    return i;
            }
            return null;          
        }

        /// <summary>
        /// Вернуть сотрудника по логину
        /// </summary>
        /// <param name="Login"></param>
        /// <returns></returns>
        public Employeer GetEmployeerByLogin(string Login)
        {
            List<Employeer> l = GetEmplList(true, _Departments);
            foreach (Employeer i in l)
            {
                if (i.Login.ToUpper()   == Login.ToUpper ())
                    return i;
            }
            return null;          

        }
        
        public List<AdressPropramItem> GetAdressPropramItems()
        {   
            List<AdressPropramItem> res = new List<AdressPropramItem>();
            //TreeDictionaryItem[] items = AgencyLib_GlobalConstants.TreeDictionaryContext.GetAdressProgrammAsArray();

            //foreach (TreeDictionaryItem item in items)
            //{
            //    bool sel = (AdressPrograms[item.ID] != null);
            //    //AdressPropramItem i = new AdressPropramItem() { ID = item.ID, Name = item.Name, Selected = sel };
            //    AdressPropramItem i = new AdressPropramItem() { ID = item.ID,  Selected = sel };
            //    res.Add(i);
           //}
            return res;

        }

        
        
        public void Set_UseAdressProgramm(string TreeDictionaryID, bool value)
        {

            bool b = value;
            if (b)
            {
                AdressPrograms.Remove(TreeDictionaryID);
                AdressPrograms.Add(new EntitySingle() { ID = TreeDictionaryID });
            }
            else
                AdressPrograms.Remove(TreeDictionaryID);

        }

        /// <summary>
        /// Возвращеает истину если в настройках - использовать системную папку справочника
        /// </summary>
        /// <param name="?"></param>
        /// <param name="TreeDictionaryID"></param>
        public bool CheckSetting_UseSystemDictionary(string TreeDictionaryID)
        {
            DictionarySettings.Reset();
            return (DictionarySettings[TreeDictionaryID] == null);
        }

        public override void Save()
        {
            base.SaveWitchChild();
        }

        #endregion

        #region Tools
        private void NextDeparment(Department d, Func<Department, bool> f)
        {
            if (null == d)
                return;

            if (f(d)) return;
            foreach (Department item in d.ChildNodes)
            {
                NextDeparment(item, f);
            }
        }
        #endregion

        


        //#region IFileSignature Members

        //public string Directory
        //{
        //    get { return "Agency"; }
        //}

        //public string FileName
        //{
        //    get { return ID+".xml"; }
        //}

        //#endregion
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///// <summary>
    ///// Коллекция содержит только переопределенные фабрики
    ///// Если нет переопределенной - возвращает стандартную
    ///// </summary>
    public class WS_FactoryList : EntityList
    {
        public const string wsKey_Agency = "Agency";
        public const string wsKey_Face = "Face";
        public const string wsKey_Contract = "Contract";
        public const string wsKey_Constraction = "Constraction";
        public const string wsKey_Task = "Task";
        public const string wsKey_WhereFilters = "WhereFilter";
        public const string wsKey_Dictionary = "Dictionary";
        public const string wsKey_BusinesEngine = "BusinesEngine";

        public override EntitySingle this[object KeyValue]
        {
            get
            {
                EntitySingle obj = base[KeyValue];
                if (null != obj)
                    return obj;

                switch (KeyValue.ToString())
                {
                    case wsKey_Agency:
                        return new wsAgency();
                    case wsKey_Face:
                        return new wsFace();
                    case wsKey_Contract:
                        return new wsContract();
                    case wsKey_Task:
                        return new wsTask();
                    case wsKey_Dictionary:
                        return new wsDictionary();
                    case wsKey_Constraction:
                        return new wsConstractions();

                    



                    default:
                        return null;
                }
            }
        }

    }


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary>
    /// адресные программы доступные агенству
    /// </summary>
    public class AdressPropramItem
    {
        public string ID { get; set; }
        public string Name { get; set; }
        public bool Selected { get; set; }
        public DateTime CreateDate { get; set; }
        public DateTime LastUpdate { get; set; }

    }

}

